import ts = require('typescript');

const VISIT_BLANKED = '';
const VISITED_JS = null;
type VisitResult = typeof VISIT_BLANKED | typeof VISITED_JS;

const genericMap = new Map();

function blankGenerics(node: ts.Node, generics: ts.NodeArray<ts.TypeNode>) {
  node.forEachChild((node) => {
    if (ts.isTypeReferenceNode(node)) {
      if (node.typeArguments) {
        blankGenerics(node, node.typeArguments);
      }
    }
  });

  generics.forEach((generic) => {
    if (ts.isTypeReferenceNode(generic)) {
      if (generic.typeArguments) {
        blankGenerics(node, generic.typeArguments);
      }
    }
  });
  // TODO: strip type
  // then: strip `<`, `>`
}
//////
interface Shape {
  accept: (v: ts.Visitor) => void;
}
//////
class InnerVisitor {
  // constructor(node: ts.Node) { }
  visitTaggedTemplate(node: ts.TaggedTemplateExpression): VisitResult {
    if (node.typeArguments) {
      blankGenerics(node, node.typeArguments);
    }
    return '';
  }
}

class StatementLike {}

const src = `function logName<T extends { name: string }>(something: T) {
  console.log(something.name);
}`;

// type Or = Omit<{ name: 'matt'; name2: 12 } & {}, never>;
// logName({ name: 'matt', name2: 12 } ); // ok

// # MARK: Compiler entry
function compile(sourceCode: string): string {
  const source = ts.createSourceFile(
    'TODO.ts', // read a file
    sourceCode,
    ts.ScriptTarget.ES2022,
    true,
    ts.ScriptKind.TS,
  );
  const transformFn: ts.TransformerFactory<any>[] = [];
  const result = ts.transform(
    source,
    /* custom transformer_func pip */ transformFn,
  );
  const printer = ts.createPrinter();
  // other to analyze? or check?
  const transformedSourceFile = result.transformed[0];

  console.log('result.transformed', result.transformed);
  const resultCode = printer.printFile(transformedSourceFile);

  return resultCode;
}
// export = compile;

const tsrc = compile(src);

console.log(tsrc);
